<?php
// +----------------------------------------------------------------------
// | 在我们年轻的城市里，没有不可能的事！
// +----------------------------------------------------------------------
// | Copyright (c) 2020 http://srs.micang.com All rights reserved.
// +----------------------------------------------------------------------
// | Author : Jansen <jansen.shi@qq.com>
// +----------------------------------------------------------------------
namespace jansen\nv\drivers;
use Metaregistrar\EPP\eppException;
use Metaregistrar\EPP\eppRequest;
use Metaregistrar\EPP\teleinfoEppConnection;
abstract class NameValidator{
    protected $response;
    private $eppClient;
    /**
     * Registry constructor.
     *
     * @param bool $logging
     * @throws \Exception
     */
    public function __construct(bool $logging=true){
        if (!($this->eppClient instanceof teleinfoEppConnection)){
            $this->eppClient = new teleinfoEppConnection($logging);
        }
    }
    /**
     * 设置服务器信息
     * @param string $host
     * @param int    $port
     * @author:Jansen <jansen.shi@qq.com>
     */
    public function setHost(string $host, int $port=700){
        $this->eppClient->setHostname($host);
        $this->eppClient->setPort($port);
    }
    /**
     * 设置连接账户信息
     * @param string $username
     * @param string $password
     * @author:Jansen <jansen.shi@qq.com>
     */
    public function setAccount(string $username, string $password){
        $this->eppClient->setUsername($username);
        $this->eppClient->setPassword($password);
    }
    /**
     * 启用证书连接
     * @param string $certfile
     * @param string $passphrase
     * @author:Jansen <jansen.shi@qq.com>
     */
    public function enableCertification(string $certfile, string $passphrase=null){
        $this->eppClient->enableCertification($certfile, $passphrase);
    }
    /**
     * 启用自签名证书
     * @param bool $selfsigned
     * @author:Jansen <jansen.shi@qq.com>
     */
    public function enableAllowSelfSigned(){
        $this->eppClient->setAllowSelfSigned(true);
    }
    /**
     * 禁用peer_name验证
     * @author:Jansen <jansen.shi@qq.com>
     */
    public function disableVerifyPeerName(){
        $this->eppClient->setVerifyPeerName(false);
    }
    /**
     * 设置日志文件路径
     * @param string $logpath 支持目录或具体文件
     * @author:Jansen <jansen.shi@qq.com>
     */
    public function setLogFile(string $logpath){
        if (empty(pathinfo($logpath, PATHINFO_EXTENSION))){
            $this->eppClient->setLogFile($logpath.(strrchr($logpath, '/')?'':'/').'nv'.date('Ymd').'.log');
        }else{
            $this->eppClient->setLogFile($logpath);
        }
    }
    /**
     * 设置连接服务器的超时时间
     * @param int $timeout
     * @author:Jansen <jansen.shi@qq.com>
     */
    public function setTimeout(int $timeout){
        $this->eppClient->setTimeout($timeout);
    }
    /**
     * 设置连接为阻塞模式
     * @author:Jansen <jansen.shi@qq.com>
     */
    public function enableConnectBlock(){
        $this->eppClient->setBlocking(true);
    }
    /**
     * 统一的请求发起方法
     * @param eppRequest $eppRequest
     * @throws \Metaregistrar\EPP\eppException
     * @author:Jansen <jansen.shi@qq.com>
     */
    protected function request(eppRequest $eppRequest){
        //是否已登录，未登录时，先做登录操作
        if (!$this->eppClient->isLoggedin() && !$this->eppClient->login(true)){
            throw new eppException('登录EPP接口失败。');
        }
        //登录成功后，才能发起请求
        $this->response = $this->eppClient->request($eppRequest);
    }
    /**
     * 域名命名检查
     * @param string $name
     * @return bool
     * @author:Jansen <jansen.shi@qq.com>
     */
    abstract public function check(string $name);
    /**
     * 获取核验时提交的原始信息（包括证件图片等）
     * @param string $code      create时返回的code
     * @param string $password  create时提交的密码
     * @return array
     * @author:Jansen <jansen.shi@qq.com>
     */
    abstract public function inputInfo(string $code, string $password=null);
    /**
     * 获取实名核验验证码
     * @param string $code      create时返回的code
     * @param string $password  create时提交的密码
     * @return array
     * @author:Jansen <jansen.shi@qq.com>
     */
    abstract public function signedCode(string $code, string $password=null);
    /**
     * 读取线下审核进度，不传id时表示读取消息ID列表，传ID时表示读取详细信息并从队列中删除当前信息
     * @param string $id
     * @return array
     * @author:Jansen <jansen.shi@qq.com>
     */
    abstract public function process(string $id=null);
    /**
     * 更新核验对象的密码，返回新密码
     * @param string $code
     * @param string $password
     * @return array
     * @author:Jansen <jansen.shi@qq.com>
     */
    abstract public function resetPassword(string $code, string $password=null);
    /**
     * 创建域名命名验证签名请求
     * @param string $name
     * @param string $rnc
     * @param string $password
     * @return mixed
     * @author:Jansen <jansen.shi@qq.com>
     */
    abstract public function nameCreate(string $name, string $rnc=null, string $password=null);
    /**
     * 创建实名认证验证签名请求
     * @param string $role      实名类型，org为组织，person为个人
     * @param string $name      证件名称，即姓名或组织名称
     * @param string $number    证件号码
     * @param string $proof     证件类型，poc为身份证，poe为组织机构代码证/工商营业执照，poot为其他证件
     * @param array  $docs      证件图片，最多3张
     * @param string $password
     * @return mixed
     * @author:Jansen <jansen.shi@qq.com>
     */
    abstract public function realNameCreate(string $role, string $name, string $number, string $proof, array $docs, string $password=null);
    /**
     * 生成复杂密码
     * @param int $length 生成的密码长度
     * @return string
     * @author:Jansen <jansen.shi@qq.com>
     */
    protected function generatePassword(int $length=12){
        $alpha = ['a','b','c','d','e','f','g','h','j','k','m','n','p','q','r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H','J','K','M','N','P','Q','R','S','T','U','V','W','X','Y','Z'];
        $number = ['0','1','2','3','4','5','6','7','8','9'];
        $symbol = ['@','#','$','%','*','+','=','_','-','^','~'];
        $symbolNum = rand(2, 3);
        $charNum = ($length - $symbolNum) / 2;
        //打乱符号数组
        shuffle($symbol);
        shuffle($alpha);
        shuffle($number);
        //随机取字符
        $result['symbol'] = array_slice($symbol, 0, $symbolNum);
        $result['number'] = array_slice($number, 0, $charNum);
        $result['alpha'] = array_slice($alpha, 0, $length-$charNum-$symbolNum);
        //合并
        $password = array_merge([], $result['symbol'], $result['alpha'], $result['number']);
        shuffle($password);
        return implode('', $password);
    }
}